package cqie.personal.frame.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import cqie.personal.frame.bo.AddModifyBO;
import cqie.personal.frame.bo.AddModifyCourseClassBO;
import cqie.personal.frame.bo.GetBO;
import cqie.personal.frame.entity.ClassInfo;
import cqie.personal.frame.entity.UserInfo;
import cqie.personal.frame.exception.DataBaseUpdateException;
import cqie.personal.frame.exception.ValidationFailException;
import cqie.personal.frame.mapper.ClassInfoMapper;
import cqie.personal.frame.mapper.UserInfoMapper;
import cqie.personal.frame.service.ClassInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cqie.personal.frame.vo.PageVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Yeeeeee
 * @since 2021-09-28
 */
@Service
public class ClassInfoServiceImpl extends ServiceImpl<ClassInfoMapper, ClassInfo> implements ClassInfoService {

    @Resource
    private ClassInfoMapper classInfoMapper;
    @Resource
    private UserInfoMapper userInfoMapper;

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public synchronized boolean addClass(AddModifyBO addModifyBO) throws ValidationFailException {
        if(addModifyBO==null){
            throw new ValidationFailException("Fehler server");
        }
        if(!addModifyBO.Validate()){
            return false;
        }
        QueryWrapper<ClassInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("class_name",addModifyBO.getName());
        if(classInfoMapper.selectCount(queryWrapper)>0){
            throw new ValidationFailException("Der name wird besessen.");
        }
        ClassInfo classInfo = new ClassInfo();
        classInfo.setClassName(addModifyBO.getName());
        Date date = new Date();
        classInfo.setCreatePerson(addModifyBO.getOperator());
        classInfo.setCreateTime(date);
        classInfo.setLastUpgradePerson(addModifyBO.getOperator());
        classInfo.setLastUpgradeTime(date);
        return classInfoMapper.insert(classInfo)==1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public synchronized boolean modifyClass(AddModifyBO addModifyBO) throws ValidationFailException {
        if(addModifyBO == null){
            throw  new ValidationFailException("服务器错误");
        }
        if(!addModifyBO.Validate()){
            return false;
        }
        if(addModifyBO.getId()==null){
            throw new ValidationFailException("未获取到修改对象");
        }
        QueryWrapper<ClassInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",addModifyBO.getId());
        ClassInfo classInfo =  classInfoMapper.selectOne(queryWrapper);
        if(classInfo == null){
            throw new ValidationFailException("修改对象不可用");
        }
        queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("id",addModifyBO.getId());
        queryWrapper.eq("class_name",addModifyBO.getName());
        if(classInfoMapper.selectCount(queryWrapper)>0){
            throw new ValidationFailException("名称被占用");
        }
        classInfo.setClassName(addModifyBO.getName());
        if(addModifyBO.getAbandon()!=null){
            classInfo.setClassAbandon(addModifyBO.getAbandon());
        }
        UpdateWrapper<ClassInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",addModifyBO.getId());
        return classInfoMapper.update(classInfo,updateWrapper)==1;
    }

    @Override
    public PageVO<List<ClassInfo>> getClassInfo(GetBO getBO) throws ValidationFailException {
        if(getBO==null){
            throw new ValidationFailException("伺服器錯誤");
        }
        QueryWrapper<ClassInfo> queryWrapper = new QueryWrapper<>();
        if(getBO.getId()!=null){
            queryWrapper.eq("id",getBO.getId());
        }
        if(getBO.getName()!=null){
            queryWrapper.like("class_name",getBO.getName());
        }
        queryWrapper.last("LIMIT "+getBO.getPageOffSet()+","+getBO.getPageSize());

        List<ClassInfo> data = classInfoMapper.selectList(queryWrapper);
        PageVO<List<ClassInfo>> result = new PageVO<>(data);
        result.setPageNo(getBO.getPageNo());
        result.setPageSize(getBO.getPageSize());
        result.setRecordCount(data.size());
        queryWrapper.last("");
        Integer totalCount = classInfoMapper.selectCount(queryWrapper);
        if(totalCount == null){
            result.setTotalCount(0);
            result.setTotalPage(0);
        }else {
            result.setTotalCount(totalCount);
            result.setTotalPage(result.getTotalCount() % result.getPageSize() == 0 ?
                    result.getTotalCount() / result.getPageSize() :
                    result.getTotalCount() / result.getPageSize() + 1);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public synchronized boolean delClass(AddModifyBO addModifyBO) throws ValidationFailException, DataBaseUpdateException {
        if (addModifyBO ==null){
            throw new ValidationFailException("server error");
        }
        if(addModifyBO.getId()==null){
            throw new ValidationFailException("no target");
        }
        QueryWrapper<ClassInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",addModifyBO.getId());
        if(classInfoMapper.selectCount(queryWrapper)!=1){
            throw new ValidationFailException("target not found");
        }
        QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();
        userInfoQueryWrapper.eq("student_class_id",addModifyBO.getId());
        if(userInfoMapper.selectCount(userInfoQueryWrapper)>0) {
            UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("student_class_id", null);
            updateWrapper.eq("student_class_id", addModifyBO.getId());

            if (userInfoMapper.update(null, updateWrapper) < 1) {
                throw new DataBaseUpdateException("error when delete student in class");
            }
        }
        if (classInfoMapper.delete(queryWrapper) != 1) {
            throw new DataBaseUpdateException("error when delete class");
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public synchronized boolean addNewCourseIntoClass(AddModifyCourseClassBO addModifyBO) throws ValidationFailException {
        if (addModifyBO==null){
            throw new ValidationFailException("服务器错误，未能获取参数");
        }
        if(addModifyBO.getClassId()==null){
            throw new ValidationFailException("未能获取到班级数据");
        }
        if(addModifyBO.getCourseId()==null){
            throw new ValidationFailException("课程不能为空");
        }
        if(addModifyBO.getTeacherUid()==null){
            throw new ValidationFailException("负责教师不能为空");
        }
        Date date = new Date();

        return classInfoMapper.addNewCourseIntoClass(addModifyBO.getCourseId(),addModifyBO.getClassId(),addModifyBO.getTeacherUid(),addModifyBO.getOperator(),date)==1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public synchronized boolean removeCourseFormClass(AddModifyBO addModifyBO) throws ValidationFailException {
        if(addModifyBO==null){
            throw new ValidationFailException("服务器未能获取到请求参数");
        }
        if(addModifyBO.getId()==null){
            throw new ValidationFailException("未能获取修改对象");
        }
        return classInfoMapper.removeCourseFormClass(addModifyBO.getId())==1;
    }
}
